# Copyright (c) Lawrence Livermore National Security, LLC and other VisIt
# Project developers.  See the top-level LICENSE file for dates and other
# details.  No copyright assignment is required to contribute to VisIt.

#******************************************************************************
# Purpose: To create a static simV2 archive containing all relevant visit 
#          libs (creates libsimV2_static_ser.a, libsimV2_static_par.a)
#
#******************************************************************************


set(VISIT_PARALLEL @VISIT_PARALLEL@)
set(OSMESA_FOUND @OSMESA_FOUND@)
set(VISIT_BINARY_DIR @VISIT_BINARY_DIR@)
set(VISIT_FORTRAN @VISIT_FORTRAN@)
set(VISIT_ENABLE_XDB @VISIT_ENABLE_XDB@)
set(CMAKE_CURRENT_BINARY_DIR "@CMAKE_CURRENT_BINARY_DIR@")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "@CMAKE_ARCHIVE_OUTPUT_DIRECTORY@")
set(CMAKE_AR "@CMAKE_AR@")
set(CMAKE_RANLIB "@CMAKE_RANLIB@")
set(TMPDIR ${CMAKE_CURRENT_BINARY_DIR}/CreateStaticSimV2)
unset(visit_libs_ser)
unset(visit_libs_par)


# want to build up a list of library files to merge into one simV2_static_ser
# For this to work with cmake, need to list the cmake targets needed.
set(VISIT_LIBS enginerpc lightweight_visit_vtk mdserverproxy mdserverrpc 
               visit_verdict visit_vtk visitcommon simV2)
set(AVT_LIBS avtdbatts avtmath avtqtviswindow avtshapelets avtview)
set(AVT_SER_LIBS avtdatabase_ser avtdbin_ser avtexpressions_ser avtfilters_ser
                 avtivp_ser avtmir_ser avtpipeline_ser avtplotter_ser
                 avtquery_ser avtviswindow_ser avtwriter_ser)
set(SIMV2_SER_LIBS simV2runtime_ser engine_ser viewercore_ser viewerrpc)
set(AVT_PAR_LIBS cognomen avtdatabase_par avtdbin_par avtexpressions_par
                 avtfilters_par avtivp_par avtmir_par avtpipeline_par
                 avtplotter_par avtquery_par avtviswindow_par avtwriter_par)
set(TP_LIBS tess2 nek5000_interp)
set(SIMV2_PAR_LIBS simV2runtime_par engine_par viewercore_par viewerrpc)
set(DDTSIM_LIBS ddtsim_static)

list(APPEND visit_libs_ser ${SIMV2_SER_LIBS} ${AVT_LIBS} ${AVT_SER_LIBS}
                           ${VISIT_LIBS} ${TP_LIBS})
if(VISIT_PARALLEL)
    list(APPEND visit_libs_par ${SIMV2_PAR_LIBS} ${AVT_LIBS} ${AVT_PAR_LIBS}
                               ${VISIT_LIBS} ${TP_LIBS})
endif()

if(OSMESA_FOUND)
    list(APPEND visit_libs_ser visit_vtk_offscreen)
    list(APPEND visit_libs_par visit_vtk_offscreen)
endif()

macro(get_enabled_plugins fname type suffix plist)
   unset(lines)
   file(READ "${fname}" lines) 
   string(REGEX REPLACE "\n" ";" lines "${lines}")
   foreach(plugin ${lines})
      string(REPLACE "PLUGIN_VERB\(" "" pname "${plugin}")
      string(REPLACE "\)" "" pname "${pname}")
      list(APPEND ${plist} "I${pname}${type}" "E${pname}${type}${suffix}")
   endforeach()
endmacro()


get_enabled_plugins("${VISIT_BINARY_DIR}/include/enabled_plots.h"
                    "Plot" "_ser" visit_libs_ser)
get_enabled_plugins("${VISIT_BINARY_DIR}/include/enabled_operators.h"
                    "Operator" "_ser" visit_libs_ser)

list(APPEND visit_libs_ser "ISimV2Database" "ESimV2Database_ser" "IVTKDatabase" "EVTKDatabase_ser")
IF(VISIT_ENABLE_XDB)
    message(STATUS "Adding XDB to SimV2 static library.")
    list(APPEND visit_libs_ser "XDBLib" "VXDB_ser" "IFieldViewXDBDatabase" "EFieldViewXDBDatabase_ser")
ENDIF(VISIT_ENABLE_XDB)

if(VISIT_PARALLEL)
    get_enabled_plugins("${VISIT_BINARY_DIR}/include/enabled_plots.h"
                        "Plot" "_par" visit_libs_par)
    get_enabled_plugins("${VISIT_BINARY_DIR}/include/enabled_operators.h"
                        "Operator" "_par" visit_libs_par)
    list(APPEND visit_libs_par "ISimV2Database" "ESimV2Database_par" "IVTKDatabase" "EVTKDatabase_par")
    IF(VISIT_ENABLE_XDB)
        message(STATUS "Adding XDB to parallel SimV2 static library.")
        list(APPEND visit_libs_par "XDBLib" "VXDB_par" "IFieldViewXDBDatabase" "EFieldViewXDBDatabase_par")
    ENDIF(VISIT_ENABLE_XDB)
endif()


function(create_archive libname liblist)
    unset(ALL_OBJS)
    make_directory(${TMPDIR})
    message("Creating ${libname}")
    # Extract every library in the list into a series of object files
    foreach(LIB ${${liblist}})
      if(EXISTS ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}/lib${LIB}.a)
	file(MAKE_DIRECTORY ${TMPDIR}/${LIB})
        message("Extracting lib${LIB}.a")
	execute_process(
            COMMAND ${CMAKE_AR} x ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}/lib${LIB}.a
            WORKING_DIRECTORY ${TMPDIR}/${LIB}
	)
	file(GLOB_RECURSE OBJS "${TMPDIR}/${LIB}/*")
	set(ALL_OBJS ${ALL_OBJS} ${OBJS})
      endif()
    endforeach(LIB)

    # Merge all extracted object files into the existing target archive
    execute_process(
	COMMAND ${CMAKE_AR} cr ${libname} ${ALL_OBJS}
        WORKING_DIRECTORY ${TMPDIR}
    )

    # Ranlib the new archive library
    execute_process(
	COMMAND ${CMAKE_RANLIB} ${libname}
        WORKING_DIRECTORY ${TMPDIR}
    )

    # Delete all leftover object files
    file(REMOVE_RECURSE ${TMPDIR})
endfunction()

create_archive("${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}/libsimV2_static_ser.a"
               visit_libs_ser)

if(VISIT_PARALLEL)
    create_archive("${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}/libsimV2_static_par.a"
                   visit_libs_par)
endif()


